home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / cuj1008.zip / 1008090A < prev    next >
Text File  |  1992-02-17  |  14KB  |  411 lines

  1. /*--------------------------------------------------*
  2.  *                                                  *
  3.  * Module:    GetTouch.c                            *
  4.  * Purpose:   To provide an intelligent interface   *
  5.  *            to the Elographics ELODEV TSR from an *
  6.  *            application that must distinguish     *
  7.  *            between button and curve type touches.*
  8.  * Author:    W. Harvey Gray                        *
  9.  * Compiler:  Microsoft 5.0                         *
  10.  *                                                  *
  11.  * External   GetTouch                              *
  12.  * Functions: InitializeTouch                       *
  13.  *            ReplayTouch                           *
  14.  *            SetButtonRadius                       *
  15.  *            TouchInfo                             *
  16.  *                                                  *
  17.  * Variables: There are no external variables used  *
  18.  *            or defined by this module.            *
  19.  *                                                  *
  20.  * Copyright 1992, W. Harvey Gray.  May be used     *
  21.  *   freely, if authorship and publication are      *
  22.  *   acknowledged.                                  *
  23.  *                                                  *
  24.  *--------------------------------------------------*/
  25.  
  26. #include <math.h>
  27. #include <stdio.h>
  28.  
  29. #include "dvrfunc.h"
  30. #include "GetTouch.h"
  31.  
  32. /*--------------------------------------------------*
  33.  *                module defines                    *
  34.  *--------------------------------------------------*/
  35.  
  36. #define TOUCH_BUF_NUM 50   /* Internal buffer size. */
  37.  
  38. /*--------------------------------------------------*
  39.  *                static variables                  *
  40.  *--------------------------------------------------*/
  41.  
  42. static boolean is_button;       /* Is a button flag */
  43. static boolean from_tbuff;  /* Touch in buffer flag */
  44. static boolean overflow;   /* Buff storage exceeded */ 
  45.  
  46. static int num_returned;      /* Total touch points */
  47. static int num_touch;      /* Count of touch points */
  48. static int ut;          /* Touch point untouch flag */
  49. static int xt;          /* Touch point x coordinate */
  50. static int yt;          /* Touch point y coordinate */
  51.  
  52. static long radius2;     /* Square of button radius */
  53. static long dist2;             /* Distance variable */
  54. static long xcen;            /* X centroid of touch */
  55. static long xsum;          /* X sum of touch points */
  56. static long ycen;            /* Y centroid of touch */
  57. static long ysum;          /* Y sum of touch points */
  58.  
  59. /*--------------------------------------------------*
  60.  *                touch buffer and pointers         *
  61.  *--------------------------------------------------*/
  62.  
  63. static struct touchit touch_information;
  64.  
  65. static struct touchit *pti = &touch_information;
  66.  
  67. static struct touchxy touch[TOUCH_BUF_NUM];
  68. static struct touchxy tub;
  69.  
  70. static struct touchxy *ptouch = &touch[0];
  71. static struct touchxy *ptub = &tub;
  72.  
  73. /*--------------------------------------------------*
  74.  *                static prototypes                 *
  75.  *--------------------------------------------------*/
  76.  
  77. static struct touchxy *buffered( boolean * );
  78. static struct touchxy *unbuffered( boolean * );
  79.  
  80. static void buffer_touch( void );
  81. static void store_touch( struct touchxy * );
  82.  
  83. /*--------------------------------------------------*
  84.  *     extern function   GetTouch()                 *
  85.  *--------------------------------------------------*/
  86.  
  87. struct touchxy *GetTouch( boolean *button ) {
  88.  
  89. /*--------------------------------------------------*
  90.  * Purpose:                                         *
  91.  *                                                  *
  92.  *   Function GetTouch doesn't accept any inputs    *
  93.  * from the caller and returns two values.  If      *
  94.  * there is a touch in progress, then GetTouch      *
  95.  * returns a pointer to a struct that contains the  *
  96.  * next touch point coordinate pair.  If no touch   *
  97.  * is in progress, then GetTouch returns a NULL     *
  98.  * pointer to a touchxy struct.  Also returned via  *
  99.  * a pointer to the boolean button variable is the  *
  100.  * logical value of the button flag.  If TRUE, then *
  101.  * the touch should be interpreted like the user    *
  102.  * touched a button.  If FALSE, then the touch      *
  103.  * should be interpreted like the user is drawing   *
  104.  * a curve.                                         *
  105.  *                                                  *
  106.  *--------------------------------------------------*/
  107.     
  108.     if ( from_tbuff )
  109.         return buffered( button );
  110.  
  111.     /*----------------------------------------------*
  112.      *   If there is no touch, then return immedi-  *
  113.      * ately pointing to a null touch point.        *
  114.      *----------------------------------------------*/
  115.  
  116.     if ( ! gettouch( &xt, &yt, &ut ) )
  117.         return (struct touchxy *) NULL;
  118.  
  119.     /*----------------------------------------------*
  120.      *   If the space in the touch buffer has been  *
  121.      * exceeded, then simply return the touch point.*
  122.      *----------------------------------------------*/
  123.  
  124.     if ( overflow )
  125.         return unbuffered( button );
  126.  
  127.     /*----------------------------------------------*
  128.      *   The last special case occurs when an       *
  129.      * untouch occurs on the first touch point.  If *
  130.      * this happens, simply return the untouch pt.  *
  131.      *----------------------------------------------*/
  132.  
  133.     else if ( ut ) {
  134.  
  135.         ptub->xt = xt;
  136.         ptub->yt = yt;
  137.         ptub->ut = ut;
  138.         *button = TRUE;
  139.  
  140.         return ptub;
  141.     }
  142.  
  143.     /*----------------------------------------------*
  144.      *   If here, then the touch point is the first *
  145.      * touch point of a new touch.  Begin by buffer-*
  146.      * ing (at most) TOUCH_BUF_NUM touch points.     *
  147.      *----------------------------------------------*/
  148.  
  149.     is_button = TRUE;      /* Assume it's a button. */
  150.     num_touch = 1;  /* Init. number of touch points */
  151.  
  152.     ptouch = &touch[0];  /* Init. touch buffer ptr. */
  153.     ptouch->xt = xt;           /* Store touch point */
  154.     ptouch->yt = yt;
  155.     ptouch->ut = ut;
  156.  
  157.     xcen = xsum = (long) xt; /* Init. touch pt cen. */
  158.     ycen = ysum = (long) yt;
  159.  
  160.     buffer_touch();        /* Fill the touch buffer */
  161.     
  162.     /*----------------------------------------------*
  163.      *   Setup so that the touch can be extracted   *
  164.      * from its internal buffer and return the      *
  165.      * first touch point.                           *
  166.      *----------------------------------------------*/
  167.  
  168.     from_tbuff = TRUE;
  169.     num_returned = 1;
  170.  
  171.     ptouch = &touch[0];
  172.     *button = is_button;
  173.  
  174.     return ptouch;
  175. }
  176.  
  177. /*--------------------------------------------------*
  178.  *     extern function   InitializeTouch()          *
  179.  *--------------------------------------------------*/
  180.  
  181. void InitializeTouch( void ) {
  182.  
  183. /*--------------------------------------------------*
  184.  * Purpose:                                         *
  185.  *                                                  *
  186.  *   Initialize the internal variables of the       *
  187.  * GetTouch module.                                 *
  188.  *                                                  *
  189.  *--------------------------------------------------*/
  190.  
  191.     is_button = FALSE;
  192.     from_tbuff = FALSE;
  193.     overflow = FALSE;
  194.  
  195.     num_returned = 0;
  196.     num_touch = 0;
  197.     ut = FALSE;
  198.     xt = 0;
  199.     yt = 0;
  200.  
  201.     radius2 = 0;
  202.     dist2 = 0;
  203.     xcen = 0;
  204.     xsum = 0;
  205.     ycen = 0;
  206.     ysum = 0;
  207.  
  208.     return;
  209. }
  210.  
  211. /*--------------------------------------------------*
  212.  *     extern function   ReplayTouch()              *
  213.  *--------------------------------------------------*/
  214.  
  215. void ReplayTouch( boolean set_button ) {
  216.  
  217. /*--------------------------------------------------*
  218.  * Purpose:                                         *
  219.  *                                                  *
  220.  *   Replays a touch, if there is one in the buffer.*
  221.  *                                                  *
  222.  *--------------------------------------------------*/
  223.     
  224.     if ( from_tbuff ) {      /* Lose, if no buffer. */
  225.  
  226.         num_returned = 0;
  227.         ptouch = &touch[-1];   /* It will be ++'ed. */
  228.         is_button = set_button;
  229.     }
  230.     return;
  231. }
  232.  
  233. /*--------------------------------------------------*
  234.  *     extern function   SetButtonRadius()          *
  235.  *--------------------------------------------------*/
  236.  
  237. void SetButtonRadius( int radius ) {
  238.  
  239. /*--------------------------------------------------*
  240.  * Purpose:                                         *
  241.  *                                                  *
  242.  *   Sends the button radius to this module.        *
  243.  *                                                  *
  244.  *--------------------------------------------------*/
  245.  
  246.     radius2 = (long) radius * radius;
  247. }
  248.  
  249. /*--------------------------------------------------*
  250.  *     extern function   TouchInfo()                *
  251.  *--------------------------------------------------*/
  252.  
  253. struct touchit *TouchInfo( void ) {
  254.  
  255. /*--------------------------------------------------*
  256.  * Purpose:                                         *
  257.  *                                                  *
  258.  *   Returns a pointer to a struct that contains    *
  259.  * touch information.                               *
  260.  *                                                  *
  261.  *--------------------------------------------------*/
  262.  
  263.     pti->xcen = (int) ( xsum / (long) num_touch );
  264.     pti->ycen = (int) ( ysum / (long) num_touch );
  265.     pti->n = num_touch;
  266.     pti->button = is_button;
  267.  
  268.     return pti;
  269. }
  270.  
  271. /*--------------------------------------------------*
  272.  *     static function   buffer_touch()             *
  273.  *--------------------------------------------------*/
  274.  
  275. static void buffer_touch( void ) {
  276.  
  277. /*--------------------------------------------------*
  278.  * Purpose:                                         *
  279.  *                                                  *
  280.  *   Fill up the touch buffer by reading and storing*
  281.  * touch points.  Several conditions stop filing    *
  282.  * the touch buffer: if there are too many touch    *
  283.  * points for the buffer, stop buffering; if the    *
  284.  * touch is determined to not be a button, then     *
  285.  * there is no need to continue buffering; or if    *
  286.  * an untouch is encountered, then quit buffering.  *
  287.  *                                                  *
  288.  *--------------------------------------------------*/
  289.  
  290.     while ( num_touch < TOUCH_BUF_NUM ) {
  291.  
  292.         if ( gettouch( &xt, &yt, &ut ) ) {
  293.  
  294.             num_touch++;
  295.             store_touch( ++ptouch );
  296.  
  297.             if ( dist2 > radius2 ) {
  298.  
  299.                 /* If here, then not a button push. */
  300.                                  /* Stop buffering. */
  301.                 is_button = FALSE;
  302.                 break;
  303.             }
  304.             if ( ut ) {
  305.                                  /* Stop buffering. */
  306.                 overflow = FALSE;
  307.                 break;
  308.             }
  309.         }
  310.     }
  311.     return;
  312. }
  313.  
  314. /*--------------------------------------------------*
  315.  *     static function   buffered()                 *
  316.  *--------------------------------------------------*/
  317.  
  318. static struct touchxy *buffered( boolean *button ) {
  319.  
  320. /*--------------------------------------------------*
  321.  * Purpose:                                         *
  322.  *                                                  *
  323.  *   Returns a buffered touch checking for the end  *
  324.  * of the internal touch buffer.  If the end of the *
  325.  * buffer is encountered, then several conditional  *
  326.  * flags are set.                                   *
  327.  *                                                  *
  328.  *--------------------------------------------------*/
  329.  
  330.     num_returned++;
  331.     ptouch++;
  332.     *button = is_button;
  333.                                /* Exhausted buffer? */
  334.  
  335.     if ( num_returned == num_touch ||
  336.          num_returned > TOUCH_BUF_NUM ) {
  337.  
  338.         from_tbuff = FALSE;
  339.         overflow = TRUE;
  340.     }
  341.                               /* Untouch buffered? */
  342.     if ( ptouch->ut ) {
  343.  
  344.         from_tbuff = FALSE;
  345.         overflow = FALSE;
  346.     }
  347.     return ptouch;
  348. }
  349.  
  350. /*--------------------------------------------------*
  351.  *     static function   store_touch()              *
  352.  *--------------------------------------------------*/
  353.  
  354. static void store_touch( struct touchxy *pt ) {
  355.  
  356. /*--------------------------------------------------*
  357.  * Purpose:                                         *
  358.  *                                                  *
  359.  *   Stores touch point into a touch point struct   *
  360.  * and calculates the instantaneous average touch   *
  361.  * coordinates and the distance between this touch  *
  362.  * point's coordinate and the touches average coor- *
  363.  * dinate.                                          *
  364.  *                                                  *
  365.  *--------------------------------------------------*/
  366.  
  367.     pt->xt = xt;
  368.     pt->yt = yt;
  369.     pt->ut = ut;
  370.  
  371.     xsum += xt;
  372.     ysum += yt;
  373.     xcen = xsum / (long) num_touch;
  374.     ycen = ysum / (long) num_touch;
  375.  
  376.     dist2 = (xt - xcen) * (xt - xcen) +
  377.             (yt - ycen) * (yt - ycen);
  378.     return;
  379. }
  380.  
  381. /*--------------------------------------------------*
  382.  *     static function   unbuffered()               *
  383.  *--------------------------------------------------*/
  384.  
  385. static struct touchxy *unbuffered( boolean *button ) {
  386.  
  387. /*--------------------------------------------------*
  388.  * Purpose:                                         *
  389.  *                                                  *
  390.  *   Returns an unbuffered touch point.             *
  391.  * Additionally, it sets the button                 *
  392.  * flag if it is determined that the touch's        *
  393.  * distance exceeds the button's radius.            *
  394.  *                                                  *
  395.  *--------------------------------------------------*/
  396.  
  397.     num_touch++;
  398.     store_touch( ptub );
  399.  
  400.     if ( dist2 > radius2 ) {
  401.  
  402.         is_button = FALSE;   /* Touch is a button. */
  403.     }
  404.     *button = is_button;
  405.  
  406.     if ( ut )       /* If untouch, reset function. */
  407.         overflow = FALSE;
  408.  
  409.     return ptub;
  410. }                                  /* End of file. */
  411.